7.04. Справочник по Jenkins
Справочник по Jenkins
Общие сведения
Jenkins — это система непрерывной интеграции и непрерывной доставки (CI/CD), написанная на Java. Она автоматизирует сборку, тестирование и развертывание программного обеспечения. Jenkins работает как серверное приложение и предоставляет веб-интерфейс для управления задачами, конфигурациями и выполнением процессов.
Jenkins поддерживает расширение функциональности через плагины. Экосистема содержит более 1800 официальных плагинов, охватывающих интеграцию с системами контроля версий, облачными платформами, базами данных, контейнерами, инструментами мониторинга и многими другими технологиями.
Jenkins может работать в двух режимах:
- Freestyle-проекты — классический способ определения заданий через графический интерфейс.
- Pipeline-проекты — современный подход, основанный на декларативном или скриптовом описании процесса в виде кода (Pipeline as Code).
Архитектура Jenkins
Jenkins состоит из следующих ключевых компонентов:
Master-узел
Master-узел управляет планированием заданий, хранением конфигураций, веб-интерфейсом и взаимодействием с агентами. Он не обязан выполнять сами задания, особенно в распределенных средах.
Агенты (агентские узлы, worker nodes)
Агенты выполняют задания, назначенные master-узлом. Они могут быть:
- локальными (на том же хосте, что и master),
- удаленными (через SSH, JNLP или Docker),
- динамическими (в облаке или в Kubernetes).
Агенты регистрируются в master-узле и получают метки, по которым Jenkins направляет к ним выполнение заданий.
Плагины
Плагины добавляют поддержку новых инструментов, протоколов, шагов и возможностей. Установка происходит через веб-интерфейс или файловую систему ($JENKINS_HOME/plugins).
Конфигурационные файлы
Основные файлы конфигурации находятся в директории $JENKINS_HOME:
config.xml— глобальная конфигурация Jenkins.jobs/— описание каждого задания.nodes/— описание агентов.credentials.xml— учетные данные (если не используется плагин Credentials Binding).plugins/— установленные плагины.
Типы заданий (Job Types)
Jenkins поддерживает несколько типов заданий:
Freestyle Project
Классическое задание, настраиваемое через веб-интерфейс. Содержит этапы:
- ограничения по месту запуска,
- управление исходным кодом (SCM),
- шаги сборки,
- действия после сборки.
Pipeline
Задание, определяемое в виде скрипта Groovy. Поддерживает два синтаксиса:
- Declarative Pipeline — строгая структура с предопределенными секциями.
- Scripted Pipeline — гибкий сценарий на Groovy с полным контролем над логикой.
Multibranch Pipeline
Автоматически обнаруживает ветки в репозитории и создает отдельный pipeline для каждой ветки. Использует файл Jenkinsfile в корне каждой ветки.
Organization Folder
Группирует репозитории по организации (например, GitHub Organization). Автоматически сканирует все репозитории и применяет Multibranch Pipeline ко всем, содержащим Jenkinsfile.
External Job
Интегрирует внешние процессы, не управляемые Jenkins напрямую, но отправляющие результаты выполнения в Jenkins.
Matrix Project (через плагин)
Позволяет запускать одно задание с разными комбинациями параметров (например, ОС × версия JDK).
Pipeline: основы
Pipeline описывается в файле Jenkinsfile, который должен находиться в корне репозитория (при использовании Pipeline as Code).
Декларативный синтаксис
Структура декларативного pipeline:
pipeline {
agent any
environment { }
options { }
parameters { }
triggers { }
stages {
stage('Build') {
steps { }
}
}
post { }
}
Блок agent
Определяет, где будет выполняться pipeline или его этап.
Возможные значения:
any— любой доступный агент.none— этапы должны указывать собственный агент.label 'name'— агент с указанной меткой.node { label '...' }— аналогично, но с дополнительными параметрами.docker 'image'— запуск в контейнере Docker.dockerfile [true]— сборка образа из Dockerfile в репозитории.kubernetes— запуск в кластере Kubernetes (требуется плагин).
Пример:
agent { label 'linux && docker' }
Блок environment
Определяет переменные окружения для всего pipeline или конкретного этапа.
Пример:
environment {
DB_HOST = 'localhost'
BUILD_NUMBER = "${BUILD_NUMBER}"
}
Поддерживается маскирование чувствительных значений через credentials():
environment {
AWS_SECRET_KEY = credentials('aws-secret-key-id')
}
Блок options
Настраивает поведение pipeline.
Часто используемые опции:
buildDiscarder(logRotator(...))— управление хранением сборок.disableConcurrentBuilds()— запрет параллельных запусков.timeout(time: 1, unit: 'HOURS')— таймаут выполнения.retry(3)— повтор при падении.skipDefaultCheckout()— пропуск автоматического клонирования репозитория.timestamps()— добавление временных меток к логам.ansiColor('xterm')— поддержка цветных логов (требуется плагин).
Пример:
options {
timeout(time: 30, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr: '10'))
}
Блок parameters
Определяет параметры, запрашиваемые при ручном запуске.
Типы параметров:
string(name: 'VERSION', defaultValue: '1.0', description: '')booleanParam(name: 'DEPLOY', defaultValue: false)choice(name: 'ENV', choices: ['dev', 'stage', 'prod'])text(name: 'NOTES', defaultValue: '')password(name: 'SECRET', defaultValue: '')fileParam(name: 'UPLOAD_FILE')— загрузка файла (ограничено).
Пример:
parameters {
string(name: 'APP_NAME', defaultValue: 'myapp')
choice(name: 'TARGET_ENV', choices: ['test', 'prod'])
}
Блок triggers
Определяет автоматические триггеры запуска.
Поддерживаемые триггеры:
cron('H 2 * * *')— запуск по расписанию (аналог crontab).pollSCM('H/5 * * * *')— опрос SCM на изменения.upstream(upstreamProjects: 'other-job', threshold: hudson.model.Result.SUCCESS)— запуск после успешного завершения другого задания.genericTrigger— универсальный webhook (требуется плагин Generic Webhook Trigger).
Пример:
triggers {
cron('H 3 * * 1') // каждый понедельник в 3 часа ночи
}
Блок stages
Содержит последовательность этапов (stage). Каждый этап может содержать:
stepsagentenvironmenttoolswhenpostparallel(внутриsteps)
Пример:
stages {
stage('Test') {
steps {
sh 'npm test'
}
}
}
Блок post
Определяет действия после завершения pipeline. Выполняется всегда, независимо от результата, если не указано иное.
Условия:
alwayssuccessfailureunstablechangedabortednotBuilt
Пример:
post {
failure {
emailext(
subject: "Pipeline failed: ${env.JOB_NAME}",
body: "Check: ${env.BUILD_URL}",
recipientProviders: [[$class: 'DevelopersRecipientProvider']]
)
}
}
Встроенные шаги (Steps)
В Jenkins Pipeline шаги — это атомарные действия, выполняемые в рамках этапа (stage). Они могут быть как встроенными, так и предоставленными плагинами. Ниже перечислены основные встроенные шаги, доступные без установки дополнительных плагинов.
Управление исходным кодом
checkout scm— клонирует репозиторий, указанный в настройках задания.checkout([$class: 'GitSCM', ...])— явная настройка Git через Groovy.git url: '...', branch: '...'— упрощённый способ клонирования Git-репозитория.
Выполнение команд
sh 'command'— выполнение команды в оболочке Unix/Linux/macOS.bat 'command'— выполнение команды в Windows CMD.powershell 'command'— выполнение PowerShell-скрипта (требуется плагин).
Управление файлами и директориями
deleteDir()— удаляет всё содержимое текущей рабочей директории.dir('path') { ... }— временно меняет рабочую директорию.fileExists 'filename'— проверяет существование файла (возвращаетtrue/false).readFile 'file'— читает содержимое файла как строку.writeFile file: 'name', text: 'content'— записывает текст в файл.archiveArtifacts artifacts: 'pattern', fingerprint: true— сохраняет артефакты сборки.unarchive mapping: ['pattern': 'dest']— распаковывает ранее сохранённые артефакты.
Переменные и окружение
env.VAR = 'value'— присваивание переменной окружения.withEnv(['VAR=value']) { ... }— временная установка переменных окружения.echo 'message'— вывод сообщения в лог.currentBuild.result = 'SUCCESS'— принудительная установка статуса сборки.
Учетные данные
withCredentials([string(credentialsId: 'id', variable: 'VAR')]) { ... }— безопасное использование секретов.- Поддерживаемые типы:
string— текстовый секрет.usernamePassword— логин и пароль.file— секрет в виде файла.sshUserPrivateKey— SSH-ключ.certificate— TLS-сертификат.
Пример:
withCredentials([usernamePassword(credentialsId: 'my-creds', usernameVariable: 'USER', passwordVariable: 'PASS')]) {
sh 'curl -u $USER:$PASS https://api.example.com'
}
Уведомления
emailext to: 'user@example.com', subject: '...', body: '...'— отправка email (требует плагин Email Extension).mail to: '...', subject: '...', body: '...'— базовая отправка email.slackSend channel: '#ci', message: 'Build failed'— отправка в Slack (требует плагин Slack Notification).
Работа с Docker
docker.build('image-name', '.')— сборка образа.docker.image('name').run('--rm')— запуск контейнера.docker.withRegistry('https://registry.example.com', 'creds-id') { ... }— работа с приватным registry.
Запуск других заданий
build job: 'other-job', parameters: [string(name: 'VERSION', value: '1.0')]— запуск другого pipeline.waitUntil { ... }— ожидание выполнения условия (например, завершения внешнего процесса).
Контроль потока
retry(3) { ... }— повтор блока до 3 раз при ошибке.timeout(time: 10, unit: 'MINUTES') { ... }— ограничение времени выполнения.sleep time: 30, unit: 'SECONDS'— пауза.input message: 'Continue?'— ожидание ручного подтверждения.
Работа с JSON, XML, YAML
readJSON file: 'config.json'— парсинг JSON (требует плагин Pipeline Utility Steps).readYaml file: 'config.yaml'— парсинг YAML.writeJSON file: 'out.json', json: data— запись JSON.
Тестирование и отчеты
junit 'test-results/*.xml'— публикация результатов JUnit.publishHTML target: [reportDir: 'docs', reportFiles: 'index.html']— публикация HTML-отчёта.
Условия выполнения (when)
Блок when определяет, должен ли выполняться этап. Он может содержать одно или несколько условий.
Простые условия
branch 'main'— выполняется только в веткеmain.environment name: 'DEPLOY', value: 'true'— если переменная окружения равна значению.expression { return params.DEPLOY == true }— произвольное выражение на Groovy.not { branch 'dev' }— инверсия условия.anyOf { branch 'main'; branch 'release' }— хотя бы одно из условий истинно.allOf { branch 'main'; environment name: 'PROD', value: 'true' }— все условия истинны.
Расширенные условия
changeset "**/*.js"— выполняется, если изменены JS-файлы.triggeredBy 'TimerTrigger'— запущено по расписанию.buildingTag()— выполняется при сборке тега.changelog 'regex'— проверка сообщений коммитов по регулярному выражению.
Пример:
stage('Deploy Prod') {
when {
allOf {
branch 'main'
environment name: 'ENV', value: 'prod'
expression { currentBuild.resultIsBetterOrEqualTo('SUCCESS') }
}
}
steps {
sh './deploy.sh'
}
}
Параллельное выполнение
Jenkins поддерживает параллельное выполнение этапов внутри одного stage.
Синтаксис:
stage('Test') {
parallel {
stage('Unit') {
steps { sh 'npm test' }
}
stage('Lint') {
steps { sh 'npm run lint' }
}
stage('Security') {
steps { sh 'npm audit' }
}
}
}
Особенности:
- Все параллельные этапы получают одинаковое окружение.
- Если один из этапов падает, остальные продолжают работать (если не указано иное).
- Можно использовать
failFast true, чтобы остановить все при первой ошибке.
Пример с failFast:
parallel {
failFast true
stage('A') { steps { sh '...' } }
stage('B') { steps { sh '...' } }
}
Обработка ошибок и повторы
Блок catchError
Позволяет перехватывать ошибки без остановки pipeline:
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
sh 'might-fail.sh'
}
Повтор с логикой
def retries = 3
for (int i = 0; i < retries; i++) {
try {
sh 'flaky-command'
break
} catch (Exception e) {
if (i == retries - 1) throw e
sleep time: 10, unit: 'SECONDS'
}
}
Повторное использование кода
Shared Libraries
Позволяют выносить общую логику в отдельный Git-репозиторий.
Подключение в Jenkinsfile:
@Library('my-shared-lib') _
Функции из библиотеки вызываются как обычные Groovy-методы.
Шаблоны через load
Локальный скрипт:
def utils = load 'utils.groovy'
utils.sendNotification()
Файл utils.groovy должен возвращать объект:
def sendNotification() {
echo 'Sending notification...'
}
return this
Глобальные переменные
В Jenkins Pipeline доступен набор встроенных глобальных переменных, которые предоставляют информацию о текущем запуске, окружении и системе. Эти переменные доступны как в декларативном, так и в скриптовом pipeline.
Основные переменные (env)
Переменные из объекта env доступны в любом месте pipeline:
BUILD_NUMBER— номер текущей сборки.BUILD_ID— идентификатор сборки (обычно совпадает сBUILD_NUMBER).BUILD_TAG— строка видаjenkins-${JOB_NAME}-${BUILD_NUMBER}.JOB_NAME— имя задания.JOB_BASE_NAME— имя задания без пути (например,my-folder/my-job→my-job).BRANCH_NAME— имя ветки (в Multibranch Pipeline).CHANGE_ID— идентификатор pull request (если применимо).CHANGE_URL,CHANGE_TITLE,CHANGE_AUTHOR— метаданные pull request.WORKSPACE— путь к рабочей директории на агенте.NODE_NAME— имя агента, на котором выполняется этап.EXECUTOR_NUMBER— номер исполнителя на узле.JENKINS_HOME— путь к домашней директории Jenkins (только на master).JENKINS_URL— URL-адрес Jenkins-сервера.BUILD_URL— URL текущей сборки.GIT_COMMIT— хеш последнего коммита.GIT_BRANCH— имя ветки Git (например,origin/main).GIT_URL— URL репозитория.
Пример использования:
echo "Сборка #${env.BUILD_NUMBER} для ветки ${env.BRANCH_NAME}"
Объект params
Содержит значения параметров, переданных при запуске задания:
if (params.DEPLOY_TO_PROD) {
sh './deploy.sh prod'
}
Объект currentBuild
Предоставляет доступ к метаданным текущей сборки:
currentBuild.result— результат (SUCCESS,FAILURE,UNSTABLE,ABORTED).currentBuild.displayName— отображаемое имя сборки.currentBuild.description— описание.currentBuild.duration— длительность в миллисекундах.currentBuild.rawBuild— низкоуровневый объект (требует разрешения в sandbox).
Пример:
post {
always {
echo "Сборка завершена со статусом: ${currentBuild.result}"
}
}
Объект scm
Автоматически определённый SCM-источник (в Multibranch Pipeline). Используется в checkout scm.
Параметры заданий: типы и допустимые значения
Параметры задаются в блоке parameters декларативного pipeline или через UI в Freestyle-проектах.
string
Текстовое поле.
string(
name: 'APP_VERSION',
defaultValue: '1.0.0',
description: 'Версия приложения'
)
booleanParam
Флажок.
booleanParam(
name: 'RUN_TESTS',
defaultValue: true,
description: 'Запускать ли тесты?'
)
choice
Выпадающий список.
choice(
name: 'ENVIRONMENT',
choices: ['dev', 'stage', 'prod'],
description: 'Целевая среда'
)
text
Многострочное текстовое поле.
text(
name: 'DEPLOY_NOTES',
defaultValue: 'Нет комментариев',
description: 'Заметки для деплоя'
)
password
Поле для ввода пароля (значение маскируется в логах).
password(
name: 'API_KEY',
defaultValue: '',
description: 'Секретный ключ API'
)
file
Позволяет загрузить файл при запуске (ограничено; работает только в Web UI, не в pipeline-as-code напрямую).
Примечание: в pipeline-файле
fileParamне поддерживается напрямую. Для загрузки файлов требуется использование Freestyle-проекта или внешних механизмов (например, через API).
Безопасность и Groovy Sandbox
Jenkins по умолчанию запускает pipeline-скрипты в sandbox-режиме — ограниченной среде выполнения, которая блокирует вызов потенциально опасных методов Groovy.
Что запрещено в sandbox:
- Прямой вызов
new File(...),new ProcessBuilder(...). - Доступ к
System.exit(),Runtime.exec(). - Использование
getClass(),evaluate(),this.class. - Прямой доступ к
java.lang-классам без явного разрешения.
Как обойти ограничения:
- Администратор Jenkins может одобрить сигнатуры методов через Script Approval (веб-интерфейс → Manage Jenkins → In-process Script Approval).
- Использовать Shared Libraries, помеченные как «trusted» — они выполняются вне sandbox.
- Писать логику с использованием только разрешённых шагов (
sh,readFile,writeFileи т.д.).
Рекомендации:
- Избегайте прямого вызова Java/Groovy-методов.
- Используйте встроенные шаги (
sh,bat,powershell) для взаимодействия с системой. - Храните секреты в Credentials Store, а не в коде.
Jenkins Configuration as Code (JCasC)
JCasC — это способ управления конфигурацией Jenkins через YAML-файл, а не через веб-интерфейс.
Включение JCasC:
- Установите плагин Configuration as Code.
- Укажите путь к YAML-файлу через переменную окружения
CASC_JENKINS_CONFIGили системное свойство. - Jenkins загрузит конфигурацию при старте.
Пример jenkins.yaml:
jenkins:
systemMessage: "Автоматизированный CI/CD сервер"
numExecutors: 2
scmCheckoutRetryCount: 3
securityRealm:
local:
allowsSignup: false
users:
- id: "admin"
password: "${ADMIN_PASSWORD}"
authorizationStrategy:
globalMatrix:
permissions:
- "Overall/Administer:admin"
- "Job/Build:authenticated"
- "Job/Read:anonymous"
nodes:
- permanent:
name: "linux-agent"
remoteFS: "/home/jenkins"
launcher:
ssh:
host: "192.168.1.10"
port: 22
credentialsId: "ssh-agent-key"
credentials:
system:
domainCredentials:
- credentials:
- string:
scope: GLOBAL
id: "docker-hub-password"
secret: "${DOCKER_HUB_PASSWORD}"
description: "Пароль от Docker Hub"
jobs:
- script: >
pipelineJob('example-app') {
definition {
cpsScm {
scriptPath('Jenkinsfile')
scm {
git('https://github.com/user/repo.git', 'main')
}
}
}
}
Преимущества JCasC:
- Конфигурация версионируется вместе с кодом.
- Возможность воспроизводимого развёртывания.
- Устранение «ручной настройки» на продакшен-сервере.
Переменные окружения в JCasC:
Используйте ${VAR_NAME} для подстановки значений из окружения. Например, ${ADMIN_PASSWORD} будет заменён на значение переменной ADMIN_PASSWORD.